﻿using System;
using System.IO;
using System.Reflection;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using rpc_service.cache;
using rpc_service.config;
using rpc_service.core.poll;
using rpc_service.core.registry;
using rpc_service.log;
using Microsoft.Extensions.Logging;

namespace rpc_service.core.support.assembly.roslyn;

public class RoslynGenerate : RPCGenerate<RoslynStep>
{
    private RoslynReferences _roslynReferences = new RoslynReferences();
    private RPCClassLoader _rpcClassLoader = new RPCClassLoader();
    private ILogger _logger = Logger.GetLoggerFactory().CreateLogger("RoslynGenerate");
    
    public RoslynGenerate()
    {
        Type registryType = RegistryManager.GetRegistryType(LoadConfig.Load());
        
        RoslynStep[] methodSteps = new RoslynStep[]
        {
            new RoslynMethodGetHttpMethodStep(_rpcClassLoader.InterceptorClassLoader(), "RandomPoll".GetTypeByStr(), registryType),
            new RoslynMethodPostHttpMethodStep(_rpcClassLoader.InterceptorClassLoader(), "RandomPoll".GetTypeByStr(), registryType),
        };
        
        _steps = new RoslynStep[]
        {
            new RoslynClassStep(methodSteps)
        };
    }
    
    public override object Generate(Type targetType)
    {
        StringBuilder proxy = new StringBuilder();

        _steps[0].process(proxy, targetType, null);
        
        string sourceCode = proxy.ToString();
        
        // 调试用：输出生成的源代码
        _logger.LogInformation($"为 {targetType.FullName} 生成的代理源代码:");

        Assembly assembly = compileCode(sourceCode);
        
        // 添加空检查，防止类型不存在
        var proxyType = assembly.GetType($"DynamicProxy.{targetType.Name}Proxy");
        if (proxyType == null)
        {
            // 输出程序集中所有可用类型
            _logger.LogInformation("程序集中可用的类型:");
            foreach (var type in assembly.GetTypes())
            {
                _logger.LogInformation($" - {type.FullName}");
            }
            throw new Exception($"无法找到动态生成的类型: DynamicProxy.{targetType.Name}Proxy");
        }
        
        // 尝试创建实例并返回
        try {
            return Activator.CreateInstance(proxyType)!;
        }
        catch (Exception ex) {
            throw new Exception($"无法实例化代理类型 {proxyType.FullName}: {ex.Message}", ex);
        }
    }
    
    private Assembly compileCode(string sourceCode)
    {
        // 创建语法树
        SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(sourceCode);
            
        // 获取基础引用
        var references = _roslynReferences.GenerateReferences();
        
        // 创建编译
        CSharpCompilation compilation = CSharpCompilation.Create(
            $"DynamicProxy_{Guid.NewGuid()}",
            new[] { syntaxTree },
            references,
            new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
            
        // 编译到内存流
        using (var ms = new MemoryStream())
        {
            var result = compilation.Emit(ms);
                
            if (!result.Success)
            {
                // 处理编译错误
                var failures = result.Diagnostics.Where(diagnostic => 
                    diagnostic.IsWarningAsError || 
                    diagnostic.Severity == DiagnosticSeverity.Error);
                
                StringBuilder errorMessages = new StringBuilder();
                foreach (var diagnostic in failures)
                {
                    errorMessages.AppendLine($"{diagnostic.Id}: {diagnostic.GetMessage()}");
                    _logger.LogError($"{diagnostic.Id}: {diagnostic.GetMessage()}");
                }
                    
                throw new Exception($"代码编译失败: {errorMessages}");
            }
                
            ms.Seek(0, SeekOrigin.Begin);
            return Assembly.Load(ms.ToArray());
        }
    }
}